const gridSize = 4;
const gridLength = 100;
const gridGap = 10;
const boardSize = gridLength * gridSize + gridGap * (gridSize + 1);
const gridColor = "#cdc1b4";
const backgroundColor = "#bbada0";
const numberColors = {
  0: "#776e65",
  2: "#eee4da",
  4: "#ede0c8",
  8: "#f2b179",
  16: "#f59563",
  32: "#f67c5f",
  64: "#f65e3b",
  128: "#edcf72",
  256: "#edcc61",
  512: "#edc850",
  1024: "#edc53f",
  2048: "#edc22e",
  4096: "#3c3a32"
};

let board;
let score;
let gameOver = true;
let selectedRow = null;
let selectedCol = null;
let cells;

function resetGame() {
  board = Array(gridSize).fill().map(() => Array(gridSize).fill(0));
  score = 0;
  gameOver = false;
  selectedRow = null;
  selectedCol = null;

  const gameBoard = document.querySelector(".game-board");
  gameBoard.innerHTML = "";

  for (let i = 0; i < gridSize; i++) {
    const row = document.createElement("div");
    row.classList.add("row");
    gameBoard.appendChild(row);

    for (let j = 0; j < gridSize; j++) {
      const cell = document.createElement("div");
      cell.classList.add("cell");
      cell.classList.add("zero");
      cell.setAttribute("data-row", i);
      cell.setAttribute("data-col", j);
      cell.addEventListener("click", () => {
        if (gameOver || board[i][j] === 0) {
          return;
        }

        if (selectedRow === null && selectedCol === null) {
          selectedRow = i;
          selectedCol = j;
          cell.classList.add("selected");
        } else {
          const startPos = [selectedRow, selectedCol];
          const endPos = [i, j];
          move(startPos, endPos);
          cell.classList.remove("selected");
          selectedRow = null;
          selectedCol = null;
        }
      });
      row.appendChild(cell);
    }
  }
  const scoreDiv = document.querySelector(".score");
  scoreDiv.innerHTML = "Score: 0"; // reset score to 0

  cells = document.querySelectorAll(".cell"); // re-assign cells variable
  updateGrid();
}

function move(startPos, endPos) {
  const [x1, y1] = startPos;
  const [x2, y2] = endPos;

  if (x1 === x2 && y1 === y2) {
    return;
  }

  if (board[x2][y2] === 0) {
    board[x2][y2] = board[x1][y1];
    board[x1][y1] = 0;
    updateGrid();
    addNumber();
  } else if (board[x2][y2] === board[x1][y1]) {
    board[x2][y2] *= 2;
    score += board[x2][y2];
    board[x1][y1] = 0;
    updateGrid();
    addNumber();
    checkGameOver();
  }
}

function addNumber() {
  if (gameOver) {
    return;
  }

  while (true) {
    const randomRow = Math.floor(Math.random() * gridSize);
    const randomCol = Math.floor(Math.random() * gridSize);
    if (board[randomRow][randomCol] === 0) {
      board[randomRow][randomCol] = Math.random() > 0.5 ? 2 : 4;
      break;
    }
  }
  updateGrid();
}

function updateGrid() {
  cells = document.querySelectorAll(".cell");

  for (let i = 0; i < gridSize; i++) {
    for (let j = 0; j < gridSize; j++) {
      const cell = cells[i * gridSize + j];
      cell.classList.remove("selected");
      cell.classList.remove("zero");
      cell.style.backgroundColor = gridColor;
      if (board[i][j] === 0) {
        cell.classList.add("zero");
      } else {
        cell.textContent = board[i][j];
        cell.style.color = numberColors[board[i][j]];
      }
    }
  }
  document.querySelector(".score").textContent = `Score: ${score}`;
}

function checkGameOver() {
  if (gameOver) {
    return;
  }

  const moves = [
    [-1, 0],
    [1, 0],
    [0, -1],
    [0, 1],
  ];

  let hasMove = false;
  for (let i = 0; i < gridSize; i++) {
    for (let j = 0; j < gridSize; j++) {
      if (board[i][j] === 0) {
        hasMove = true;
        break;
      }

      for (let k = 0; k < moves.length; k++) {
        const [rowMove, colMove] = moves[k];
        const newRow = i + rowMove;
        const newCol = j + colMove;
        if (newRow >= 0 && newRow < gridSize &&
          newCol >= 0 && newCol < gridSize &&
          board[i][j] === board[newRow][newCol]) {
          hasMove = true;
          break;
        }
      }
      if (hasMove) {
        break;
      }
    }
    if (hasMove) {
      break;
    }
  }

  if (!hasMove) {
    gameOver = true;
    document.querySelector(".game-over").style.display = "block";
  }
}